#include "render_system/trackball.h"

Trackball::Trackball()
{

}


Trackball::~Trackball()
{

}


void Trackball::startPoint(const glm::vec2& start)
{
    _startPoint = map2Sphere(start);
}


void Trackball::endPoint(const glm::vec2& end)
{
    _endPoint = map2Sphere(end);
}


glm::mat4 Trackball::GetRotateMatrix()
{
    glm::vec3 normal = glm::cross(_startPoint, _endPoint);

    glm::float_t radian = glm::dot(_startPoint, _endPoint);

    radian = glm::acos(radian);

    glm::quat qua(radian, normal);

    return glm::mat4_cast(qua);
}


glm::vec3 Trackball::map2Sphere(const glm::vec2& vec)
{
    glm::vec2 point = ((glm::float_t)2.0 * (vec - _leftTopPoint) - _windowSize) / _windowSize;

    glm::float_t length = glm::length(point);
    if (1.0 <= length)
    {
        glm::vec2 tmp = glm::normalize(point);
        return glm::vec3(tmp, 0);
    }
    else
    {
        glm::float_t z = glm::sqrt(1-length);
        return glm::vec3(point, z);
    }
}


void Trackball::setBound( int leftTopX, int leftTopY, int iWidth, int iHeight )
{
    _leftTopPoint.x = (float)leftTopX;
    _leftTopPoint.y = (float)leftTopY;

    _windowSize.x = (float)iWidth;
    _windowSize.y = (float)iHeight;
}
